package com.company.aicrawlers.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.company.aicrawlers.analysis.ProductRecognizer;
import com.company.aicrawlers.analysis.StrengthJudge;
import com.company.aicrawlers.common.util.JsonUtils;
import com.company.aicrawlers.entity.*;
import com.company.aicrawlers.mapper.*;
import com.company.aicrawlers.service.AnalysisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 分析服务实现
 *
 * @author AI Crawlers Team
 * @date 2025-10-11
 */
@Slf4j
@Service
public class AnalysisServiceImpl implements AnalysisService {

    @Autowired
    private CollectResultMapper collectResultMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Autowired
    private CollectTaskMapper collectTaskMapper;

    @Autowired
    private AnalysisTaskMapper analysisTaskMapper;

    @Autowired
    private AnalysisTaskSummaryMapper taskSummaryMapper;

    @Autowired
    private AnalysisProductDetailMapper productDetailMapper;

    @Autowired
    private AnalysisQuestionResultMapper questionResultMapper;

    @Autowired
    private AnalysisRecognitionDetailMapper recognitionDetailMapper;

    @Autowired
    private ProductRecognizer productRecognizer;

    @Autowired
    private StrengthJudge strengthJudge;

    @Autowired
    private QuestionProductMapper questionProductMapper;

    @Autowired
    private QuestionCategoryMapper questionCategoryMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long analyze(Long collectTaskId) {
        log.info("========== 开始分析任务：collectTaskId={} ==========", collectTaskId);

        // 1. 创建分析任务
        AnalysisTask task = createAnalysisTask(collectTaskId);
        Long analysisId = task.getAnalysisId();

        try {
            // 2. 更新状态为运行中
            updateTaskStatus(analysisId, "running", null);

            // 3. 加载数据
            log.info("加载采集数据...");
            List<CollectResult> results = collectResultMapper.selectList(
                    new LambdaQueryWrapper<CollectResult>()
                            .eq(CollectResult::getTaskId, collectTaskId)
            );
            log.info("加载到采集结果：{}条", results.size());

            if (results.isEmpty()) {
                throw new RuntimeException("采集结果为空，无法分析");
            }

            // 4. 按问句分组采集结果（⭐优化点）
            log.info("按问句分组采集结果...");
            Map<Long, List<CollectResult>> groupedByQuestion = results.stream()
                    .collect(Collectors.groupingBy(CollectResult::getQuestionId));
            log.info("共{}个问句分组", groupedByQuestion.size());

            // 5. 逐问句识别商品（⭐优化点）
            log.info("开始逐问句识别商品...");
            List<AnalysisRecognitionDetail> allRecognitions = new ArrayList<>();
            
            int processedQuestions = 0;
            for (Map.Entry<Long, List<CollectResult>> entry : groupedByQuestion.entrySet()) {
                Long questionId = entry.getKey();
                List<CollectResult> questionResults = entry.getValue();
                
                // 获取该问句的相关商品（⭐核心优化）
                List<Product> relevantProducts = getRelevantProducts(questionId);
                log.debug("问句{}相关商品{}个", questionId, relevantProducts.size());
                
                // 识别该问句的所有结果
                List<AnalysisRecognitionDetail> recognitions = 
                    recognizeProducts(analysisId, questionResults, relevantProducts);
                allRecognitions.addAll(recognitions);
                
                processedQuestions++;
                if (processedQuestions % 10 == 0) {
                    log.info("已处理{}/{}个问句", processedQuestions, groupedByQuestion.size());
                }
            }
            
            log.info("识别完成：共识别到{}条商品记录", allRecognitions.size());

            if (!allRecognitions.isEmpty()) {
                recognitionDetailMapper.batchInsert(allRecognitions);
                log.info("识别明细保存成功");
            }

            // 6. 生成三个模块的分析结果
            log.info("生成分析结果...");
            generateTaskSummary(analysisId, collectTaskId, allRecognitions, results);
            generateProductDetails(analysisId, allRecognitions);
            generateQuestionResults(analysisId, allRecognitions, results);

            // 7. 更新任务状态为完成
            updateTaskStatus(analysisId, "completed", null);
            updateTaskStatistics(analysisId, results.size(), allRecognitions);

            log.info("========== 分析完成：analysisId={} ==========", analysisId);
            return analysisId;

        } catch (Exception e) {
            log.error("分析失败：analysisId={}", analysisId, e);
            updateTaskStatus(analysisId, "failed", e.getMessage());
            throw new RuntimeException("分析失败：" + e.getMessage(), e);
        }
    }

    @Override
    public Object getAnalysisTask(Long analysisId) {
        return analysisTaskMapper.selectById(analysisId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAnalysis(Long analysisId) {
        log.info("========== 开始删除分析任务：analysisId={} ==========", analysisId);
        
        // 1. 删除识别明细
        int count1 = recognitionDetailMapper.delete(
            new LambdaQueryWrapper<AnalysisRecognitionDetail>()
                .eq(AnalysisRecognitionDetail::getAnalysisId, analysisId)
        );
        log.info("已删除{}条识别明细", count1);
        
        // 2. 删除问句结果
        int count2 = questionResultMapper.delete(
            new LambdaQueryWrapper<AnalysisQuestionResult>()
                .eq(AnalysisQuestionResult::getAnalysisId, analysisId)
        );
        log.info("已删除{}条问句结果", count2);
        
        // 3. 删除商品详情
        int count3 = productDetailMapper.delete(
            new LambdaQueryWrapper<AnalysisProductDetail>()
                .eq(AnalysisProductDetail::getAnalysisId, analysisId)
        );
        log.info("已删除{}条商品详情", count3);
        
        // 4. 删除汇总
        int count4 = taskSummaryMapper.delete(
            new LambdaQueryWrapper<AnalysisTaskSummary>()
                .eq(AnalysisTaskSummary::getAnalysisId, analysisId)
        );
        log.info("已删除{}条汇总数据", count4);
        
        // 5. 删除任务
        analysisTaskMapper.deleteById(analysisId);
        log.info("已删除分析任务");
        
        log.info("========== 删除分析任务完成 ==========");
    }

    /**
     * 创建分析任务
     */
    private AnalysisTask createAnalysisTask(Long collectTaskId) {
        CollectTask collectTask = collectTaskMapper.selectById(collectTaskId);
        if (collectTask == null) {
            throw new RuntimeException("采集任务不存在：" + collectTaskId);
        }

        AnalysisTask task = new AnalysisTask();
        task.setCollectTaskId(collectTaskId);
        task.setAnalysisName(collectTask.getTaskName() + " - 分析");
        task.setAnalysisStatus("pending");
        task.setStartTime(LocalDateTime.now());

        analysisTaskMapper.insert(task);
        log.info("分析任务创建成功：analysisId={}", task.getAnalysisId());

        return task;
    }

    /**
     * 识别商品
     */
    private List<AnalysisRecognitionDetail> recognizeProducts(
            Long analysisId,
            List<CollectResult> results,
            List<Product> products) {

        List<AnalysisRecognitionDetail> recognitions = new ArrayList<>();

        for (CollectResult result : results) {
            String text = result.getAnswerContent();
            if (text == null || text.trim().isEmpty()) {
                continue;
            }

            // 识别商品
            List<ProductRecognizer.ProductMatch> matches = productRecognizer.recognize(text, products);

            // 转换为识别明细
            for (ProductRecognizer.ProductMatch match : matches) {
                Product product = match.getProduct();

                AnalysisRecognitionDetail detail = new AnalysisRecognitionDetail();
                detail.setAnalysisId(analysisId);
                detail.setCollectResultId(result.getResultId());
                detail.setQuestionId(result.getQuestionId());
                detail.setPlatformName(result.getPlatformName());

                detail.setProductId(product.getProductId());
                detail.setProductName(product.getProductName());
                detail.setBrandName(product.getBrand());

                detail.setRanking(match.getRanking());
                detail.setPositionIndex(match.getPositionIndex());
                detail.setMatchedKeyword(match.getMatchedKeyword());
                detail.setMatchMethod("keyword");

                // 判断推荐强度
                String strength = strengthJudge.judge(text, match.getRanking());
                detail.setStrength(strength);

                // 标记我方产品和竞品
                detail.setIsOurProduct(product.getIsOurProduct());
                detail.setIsCompetitor(product.getIsOurProduct() == 1 ? 0 : 1);

                recognitions.add(detail);
            }
        }

        return recognitions;
    }

    /**
     * 生成任务汇总（模块1）
     */
    private void generateTaskSummary(
            Long analysisId,
            Long collectTaskId,
            List<AnalysisRecognitionDetail> recognitions,
            List<CollectResult> results) {

        log.info("生成任务汇总...");

        AnalysisTaskSummary summary = new AnalysisTaskSummary();
        summary.setAnalysisId(analysisId);
        summary.setCollectTaskId(collectTaskId);

        // 基础统计
        long questionCount = results.stream().map(CollectResult::getQuestionId).distinct().count();
        long platformCount = results.stream().map(CollectResult::getPlatformName).distinct().count();
        long productCount = recognitions.stream().map(AnalysisRecognitionDetail::getProductId).distinct().count();

        summary.setTotalQuestions((int) questionCount);
        summary.setTotalPlatforms((int) platformCount);
        summary.setTotalResults(results.size());
        summary.setTotalProducts((int) productCount);

        // 我方产品统计
        List<AnalysisRecognitionDetail> ourProducts = recognitions.stream()
                .filter(r -> r.getIsOurProduct() == 1)
                .collect(Collectors.toList());

        summary.setOurProductCount((int) ourProducts.stream()
                .map(AnalysisRecognitionDetail::getProductId).distinct().count());
        summary.setOurProductMentions(ourProducts.size());

        // 覆盖率：出现我方产品的问句数 / 总问句数
        long ourProductQuestionCount = ourProducts.stream()
                .map(AnalysisRecognitionDetail::getQuestionId).distinct().count();
        BigDecimal coverageRate = questionCount > 0
                ? BigDecimal.valueOf(ourProductQuestionCount * 100.0 / questionCount).setScale(2, RoundingMode.HALF_UP)
                : BigDecimal.ZERO;
        summary.setOurProductCoverageRate(coverageRate);

        // 平均排名
        BigDecimal avgRanking = ourProducts.isEmpty() ? BigDecimal.ZERO
                : BigDecimal.valueOf(ourProducts.stream()
                .mapToInt(AnalysisRecognitionDetail::getRanking).average().orElse(0))
                .setScale(2, RoundingMode.HALF_UP);
        summary.setOurProductAvgRanking(avgRanking);

        // 平台分布（简化版，直接统计）
        Map<String, Long> platformDist = ourProducts.stream()
                .collect(Collectors.groupingBy(AnalysisRecognitionDetail::getPlatformName, Collectors.counting()));
        // TODO: 转换为JSON格式存储

        // 竞品统计
        List<AnalysisRecognitionDetail> competitors = recognitions.stream()
                .filter(r -> r.getIsCompetitor() == 1)
                .collect(Collectors.toList());

        summary.setCompetitorCount((int) competitors.stream()
                .map(AnalysisRecognitionDetail::getProductId).distinct().count());
        summary.setCompetitorMentions(competitors.size());

        // TODO: Top5竞品统计

        taskSummaryMapper.insert(summary);
        log.info("任务汇总生成成功");
    }

    /**
     * 生成商品分析（模块2）
     */
    private void generateProductDetails(Long analysisId, List<AnalysisRecognitionDetail> recognitions) {
        log.info("生成商品分析...");

        // 按商品分组
        Map<Long, List<AnalysisRecognitionDetail>> grouped = recognitions.stream()
                .collect(Collectors.groupingBy(AnalysisRecognitionDetail::getProductId));

        List<AnalysisProductDetail> details = new ArrayList<>();

        for (Map.Entry<Long, List<AnalysisRecognitionDetail>> entry : grouped.entrySet()) {
            Long productId = entry.getKey();
            List<AnalysisRecognitionDetail> productRecognitions = entry.getValue();

            AnalysisProductDetail detail = new AnalysisProductDetail();
            detail.setAnalysisId(analysisId);
            detail.setProductId(productId);
            detail.setProductName(productRecognitions.get(0).getProductName());
            detail.setBrandName(productRecognitions.get(0).getBrandName());
            detail.setIsOurProduct(productRecognitions.get(0).getIsOurProduct());
            detail.setIsCompetitor(productRecognitions.get(0).getIsCompetitor());

            // 推荐统计
            detail.setTotalMentions(productRecognitions.size());

            long questionCoverage = productRecognitions.stream()
                    .map(AnalysisRecognitionDetail::getQuestionId).distinct().count();
            detail.setQuestionCoverage((int) questionCoverage);

            // TODO: 覆盖率计算需要总问句数

            // 平均排名
            BigDecimal avgRanking = BigDecimal.valueOf(
                    productRecognitions.stream().mapToInt(AnalysisRecognitionDetail::getRanking).average().orElse(0)
            ).setScale(2, RoundingMode.HALF_UP);
            detail.setAvgRanking(avgRanking);

            // 排名分布
            detail.setRank1Count((int) productRecognitions.stream().filter(r -> r.getRanking() == 1).count());
            detail.setRank2Count((int) productRecognitions.stream().filter(r -> r.getRanking() == 2).count());
            detail.setRank3Count((int) productRecognitions.stream().filter(r -> r.getRanking() == 3).count());
            detail.setRank45Count((int) productRecognitions.stream().filter(r -> r.getRanking() >= 4 && r.getRanking() <= 5).count());
            detail.setRank6PlusCount((int) productRecognitions.stream().filter(r -> r.getRanking() >= 6).count());

            // 推荐强度分布
            detail.setStrongCount((int) productRecognitions.stream().filter(r -> "strong".equals(r.getStrength())).count());
            detail.setMediumCount((int) productRecognitions.stream().filter(r -> "medium".equals(r.getStrength())).count());
            detail.setWeakCount((int) productRecognitions.stream().filter(r -> "weak".equals(r.getStrength())).count());

            // TODO: 平台表现和关联问句（JSON格式）

            details.add(detail);
        }

        if (!details.isEmpty()) {
            productDetailMapper.batchInsert(details);
            log.info("商品分析生成成功：{}个商品", details.size());
        }
    }

    /**
     * 生成问句分析（模块3）
     */
    private void generateQuestionResults(
            Long analysisId,
            List<AnalysisRecognitionDetail> recognitions,
            List<CollectResult> results) {

        log.info("生成问句分析...");

        // 按问句分组
        Map<Long, List<AnalysisRecognitionDetail>> grouped = recognitions.stream()
                .collect(Collectors.groupingBy(AnalysisRecognitionDetail::getQuestionId));

        List<AnalysisQuestionResult> questionResults = new ArrayList<>();

        for (Map.Entry<Long, List<AnalysisRecognitionDetail>> entry : grouped.entrySet()) {
            Long questionId = entry.getKey();
            List<AnalysisRecognitionDetail> questionRecognitions = entry.getValue();

            // 获取问句内容
            Optional<CollectResult> resultOpt = results.stream()
                    .filter(r -> r.getQuestionId().equals(questionId))
                    .findFirst();

            if (!resultOpt.isPresent()) {
                continue;
            }

            AnalysisQuestionResult questionResult = new AnalysisQuestionResult();
            questionResult.setAnalysisId(analysisId);
            questionResult.setQuestionId(questionId);
            questionResult.setQuestionContent(resultOpt.get().getQuestionContent());

            // 基础统计
            long platformCount = questionRecognitions.stream()
                    .map(AnalysisRecognitionDetail::getPlatformName).distinct().count();
            questionResult.setPlatformCount((int) platformCount);

            long productCount = questionRecognitions.stream()
                    .map(AnalysisRecognitionDetail::getProductId).distinct().count();
            questionResult.setTotalProducts((int) productCount);

            // 我方产品表现
            List<AnalysisRecognitionDetail> ourProducts = questionRecognitions.stream()
                    .filter(r -> r.getIsOurProduct() == 1)
                    .collect(Collectors.toList());

            questionResult.setOurProductAppears(ourProducts.isEmpty() ? 0 : 1);

            if (!ourProducts.isEmpty()) {
                BigDecimal avgRanking = BigDecimal.valueOf(
                        ourProducts.stream().mapToInt(AnalysisRecognitionDetail::getRanking).average().orElse(0)
                ).setScale(2, RoundingMode.HALF_UP);
                questionResult.setOurProductAvgRanking(avgRanking);
            }

            // ========== 生成各平台推荐结果JSON（⭐核心功能） ==========
            Map<String, List<Map<String, Object>>> platformResultsMap = new LinkedHashMap<>();
            
            // 按平台分组
            Map<String, List<AnalysisRecognitionDetail>> byPlatform = questionRecognitions.stream()
                    .collect(Collectors.groupingBy(
                            AnalysisRecognitionDetail::getPlatformName,
                            LinkedHashMap::new,
                            Collectors.toList()
                    ));
            
            // 为每个平台构建商品列表
            for (Map.Entry<String, List<AnalysisRecognitionDetail>> platformEntry : byPlatform.entrySet()) {
                String platform = platformEntry.getKey();
                List<AnalysisRecognitionDetail> platformRecogs = platformEntry.getValue();
                
                // 按排名排序
                platformRecogs.sort(Comparator.comparingInt(AnalysisRecognitionDetail::getRanking));
                
                // 构建商品列表
                List<Map<String, Object>> productList = new ArrayList<>();
                for (AnalysisRecognitionDetail recog : platformRecogs) {
                    Map<String, Object> productInfo = new LinkedHashMap<>();
                    productInfo.put("ranking", recog.getRanking());
                    productInfo.put("productId", recog.getProductId());
                    productInfo.put("productName", recog.getProductName());
                    productInfo.put("brandName", recog.getBrandName());
                    productInfo.put("isOurProduct", recog.getIsOurProduct() == 1);
                    productInfo.put("isCompetitor", recog.getIsCompetitor() == 1);
                    productInfo.put("strength", recog.getStrength());
                    
                    productList.add(productInfo);
                }
                
                platformResultsMap.put(platform, productList);
            }
            
            // 转换为JSON字符串
            String platformResultsJson = JsonUtils.toJson(platformResultsMap);
            questionResult.setPlatformResults(platformResultsJson);
            
            // ========== 计算平台一致性（简化版） ==========
            // 获取所有平台共同推荐的商品
            Set<Long> allProductIds = questionRecognitions.stream()
                    .map(AnalysisRecognitionDetail::getProductId)
                    .collect(Collectors.toSet());
            
            // 计算每个商品在几个平台出现
            Map<Long, Long> productPlatformCount = questionRecognitions.stream()
                    .collect(Collectors.groupingBy(
                            AnalysisRecognitionDetail::getProductId,
                            Collectors.counting()
                    ));
            
            // 所有平台都推荐的商品数
            long commonProducts = productPlatformCount.values().stream()
                    .filter(count -> count == platformCount)
                    .count();
            
            questionResult.setCommonProducts((int) commonProducts);
            questionResult.setUniqueProducts((int) (allProductIds.size() - commonProducts));
            
            // 一致性得分：共同商品数 / 总商品数 × 100
            BigDecimal consistencyScore = allProductIds.size() > 0
                    ? BigDecimal.valueOf(commonProducts * 100.0 / allProductIds.size())
                            .setScale(2, RoundingMode.HALF_UP)
                    : BigDecimal.ZERO;
            questionResult.setConsistencyScore(consistencyScore);
            
            // 一致性级别
            String consistencyLevel;
            if (consistencyScore.compareTo(BigDecimal.valueOf(60)) >= 0) {
                consistencyLevel = "高";
            } else if (consistencyScore.compareTo(BigDecimal.valueOf(30)) >= 0) {
                consistencyLevel = "中";
            } else {
                consistencyLevel = "低";
            }
            questionResult.setConsistencyLevel(consistencyLevel);

            questionResults.add(questionResult);
        }

        if (!questionResults.isEmpty()) {
            questionResultMapper.batchInsert(questionResults);
            log.info("问句分析生成成功：{}个问句", questionResults.size());
        }
    }

    /**
     * 更新任务状态
     */
    private void updateTaskStatus(Long analysisId, String status, String errorMessage) {
        AnalysisTask task = analysisTaskMapper.selectById(analysisId);
        if (task != null) {
            task.setAnalysisStatus(status);
            if ("completed".equals(status) || "failed".equals(status)) {
                task.setEndTime(LocalDateTime.now());

                if (task.getStartTime() != null) {
                    long duration = java.time.Duration.between(task.getStartTime(), task.getEndTime()).getSeconds();
                    task.setDuration((int) duration);
                }
            }
            if (errorMessage != null) {
                task.setErrorMessage(errorMessage);
            }
            analysisTaskMapper.updateById(task);
        }
    }

    /**
     * 更新任务统计信息
     */
    private void updateTaskStatistics(Long analysisId, int totalResults, List<AnalysisRecognitionDetail> recognitions) {
        AnalysisTask task = analysisTaskMapper.selectById(analysisId);
        if (task != null) {
            task.setTotalResults(totalResults);

            long productCount = recognitions.stream()
                    .map(AnalysisRecognitionDetail::getProductId).distinct().count();
            task.setTotalProducts((int) productCount);

            task.setTotalRecognitions(recognitions.size());

            analysisTaskMapper.updateById(task);
        }
    }

    /**
     * 获取问句的相关商品（⭐核心优化方法）
     *
     * @param questionId 问句ID
     * @return 相关商品列表
     */
    private List<Product> getRelevantProducts(Long questionId) {
        Set<Long> productIds = new HashSet<>();

        // ========== 策略1：获取直接关联的商品 ==========
        List<Long> directProductIds = questionProductMapper.getProductIdsByQuestionId(questionId);
        if (directProductIds != null && !directProductIds.isEmpty()) {
            productIds.addAll(directProductIds);
            log.debug("问句{}直接关联商品{}个", questionId, directProductIds.size());
        }

        // ========== 策略2：通过类别获取商品 ==========
        // Step 1: 获取问句关联的类别
        List<String> categories = questionCategoryMapper.getCategoriesByQuestionId(questionId);
        
        if (categories != null && !categories.isEmpty()) {
            log.debug("问句{}关联类别：{}", questionId, categories);
            
            // Step 2: 获取这些类别下的所有商品ID
            List<Long> categoryProductIds = productMapper.getProductIdsByCategories(categories);
            if (categoryProductIds != null && !categoryProductIds.isEmpty()) {
                productIds.addAll(categoryProductIds);
                log.debug("类别{}下的商品{}个", categories, categoryProductIds.size());
            }
        }

        // ========== 策略3：兜底策略 ==========
        // 如果没有任何关联，使用所有启用的商品
        if (productIds.isEmpty()) {
            log.warn("问句{}没有关联商品和类别，使用所有商品（兜底策略）", questionId);
            List<Product> allProducts = productMapper.selectList(
                    new LambdaQueryWrapper<Product>().eq(Product::getStatus, 1)
            );
            return allProducts;
        }

        // ========== 批量查询商品详情 ==========
        List<Product> products = productMapper.selectBatchIds(new ArrayList<>(productIds));

        log.info("问句{}最终相关商品{}个（来源：直接关联{}个，类别扩展共{}个去重ID）",
                questionId, products.size(), 
                directProductIds != null ? directProductIds.size() : 0, 
                productIds.size());

        return products;
    }
}

